﻿
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Xml;

using NORM.DataBase;
using DevelopAssistant.Service;
using DevelopAssistant.Core.ToolBox;
using ICSharpCode.TextEditor.Document;
using ICSharpCode.WinFormsUI.Docking;
using ICSharpCode.WinFormsUI.Controls;

namespace DevelopAssistant.Core.DBMS
{
    public partial class QueryDocument : DockContent, IDocumentContent
    {
        #region 私有变量
         
        int delayTimes = 0;//延迟时间
        int commitTimes = 0;//提交次数
        int rollbackTimes = 0;//回滚次数  
        int totalselectRows = -1; //共查询出的记录数
        int totalexecuteRows = -1; //共影响行数        

        string _gloabId = string.Empty;
        string _dbTypeName = string.Empty;
        string _commandCode = string.Empty;//命令代码
        string _clipBoardValue = string.Empty;//剪切板上的字符串内容
       
        DataBase AdoObject = null;
        MainForm _MAINFORM = null;
        DataBaseServer DBServer = null;

        bool _isShowRownumber = false;//记录是否显示行号
        bool _tranBeginning = false;//事务是否开启中
        bool _unCompleteCommand = false;//未提交的命令        
        bool _enableQueryBatching = false;
        bool _backgroudWorkerCancel = false;        

        ListBox _listBox = null;

        NProgressBox ProcessBox;
        System.Threading.Tasks.Task task;        
        ITextEditorProperties _editorSettings;
        DataGridViewCellStyle _headCellStyle;       

        List<TabPage> _tabPages = new List<TabPage>();

        #endregion

        private delegate void Delegate_Commit(CommandRunner Runner);
        private delegate void Delegate_Rollback(CommandRunner Runner);
        private delegate void Delegate_ExecuteCommandText(CommandRunner Runner);

        #region 构造方法
        private QueryDocument()
        {
            ProcessBox = new NProgressBox();
            this.Controls.Add(ProcessBox);
            InitializeComponent();
            InitializeControls();
            InitializeEditor(string.Empty, "TSQL");
        }

        public QueryDocument(MainForm form)
            : this()
        {
            _MAINFORM = form;
            DBServer = _MAINFORM.ConnectedDataBaseServer;
            if (DBServer == null)
            {
                _MAINFORM.SetQueryFormToolBarItemVisible(false);
                //_MAINFORM.setQueryFormToolBarItemEnabled(false);
                _MAINFORM.SetSysStatusInfo("请先连接数据库!");
            }
            else
            {
                AdoObject = Utility.GetAdohelper(DBServer);
                try
                {
                    txtExecSqlCommand.DataBaseServer = DBServer;
                    _MAINFORM.SetQueryFormToolBarItemVisible(true);
                    _dbTypeName = DBServer.ProviderName;
                    if (string.IsNullOrEmpty(_dbTypeName))
                    {
                        _dbTypeName = _dbTypeName.Substring(_dbTypeName.LastIndexOf(".") + 1);
                    }
                    switch (DBServer.ProviderName)
                    {
                        case "System.Data.SQL":
                        case "System.Data.Sql":
                        case "System.Data.PostgreSql":
                        case "System.Data.Oracle":
                        case "System.Data.MySql":
                            if (AppSettings.EditorSettings.EnableDataBaseTran)
                            {
                                this._tranBeginning = true;
                                AdoObject.BeginTransaction();  
                            }                                                        
                            break;
                    }                
                   
                }
                catch (Exception ex)
                {                    
                    _MAINFORM.SetSysStatusInfo(ex.Message);
                }

                this.ToolTipText = DBServer.ConnectionString;

            }

            if (AppSettings.WindowTheme != null)
            {
                Type type = AppSettings.WindowTheme.GetType();
                if (type == typeof(ICSharpCode.WinFormsUI.Theme.ThemeVS2012))
                {                    
                    ResultsTabControl.Radius = 1;
                    ResultsTabControl.ItemSize = new Size(80, 28);
                }
                else if (type == typeof(ICSharpCode.WinFormsUI.Theme.ThemeMac))
                {
                    ResultsTabControl.Radius = 10;
                    ResultsTabControl.ItemSize = new Size(90, 24);
                }
                else if (type == typeof(ICSharpCode.WinFormsUI.Theme.ThemeShadow))
                {
                    ResultsTabControl.Radius = 8;
                    ResultsTabControl.ItemSize = new Size(86, 24);
                }
            }

            SetEditorFont();
        }

        #endregion

        #region 重载
        protected override void OnClosed(EventArgs e)
        {
            if (_MAINFORM != null)
            {
                _MAINFORM.SetQueryFormToolBarItemVisible(false);
                if (AdoObject != null)
                {
                    AdoObject.Commit();
                    commitTimes = commitTimes + 1;
                }
            }
            base.OnClosed(e);
        }

        #endregion

        #region 私有方法
        private void UpdateTabControlProperties()
        {
            ResultsTabControl.Radius = 1;
            ResultsTabControl.ShowClose = false;
            ResultsTabControl.TabCaptionLm = -3;
            ResultsTabControl.BorderColor = SystemColors.ControlDark;
            ResultsTabControl.ArrowColor = Color.White;
            ResultsTabControl.BaseColor = SystemColors.Control;
            ResultsTabControl.BackColor = SystemColors.Control;           
            ResultsTabControl.SizeMode = System.Windows.Forms.TabSizeMode.Fixed;          
        }

        private string MessageWriteLine(string icon, string message)
        {
            string result = string.Format("{0}：{1}", icon, message);
            return result;
        }

        //private string CreateQueryCompleteMessage(DateTime start, DateTime end,int delaytime=0)
        //{
        //    TimeSpan ts = end.Subtract(start);           
        //    double tricks = ts.TotalMilliseconds - delaytime;
        //    TimeSpan lts = TimeSpan.FromMilliseconds(tricks);
        //    string msg = string.Format(
        //        "共计用时：{0:00} 分 {1:00} 秒 {2:000} 毫秒",
        //        lts.Minutes,
        //        lts.Seconds,
        //        lts.Milliseconds);
        //    return msg;
        //}       

        private void InitializeControls()
        {
            _headCellStyle = new DataGridViewCellStyle() { Alignment =DataGridViewContentAlignment.MiddleLeft, WrapMode =DataGridViewTriState.True,
                Font =new Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))), 
                SelectionBackColor = System.Drawing.SystemColors.Highlight,
                SelectionForeColor = System.Drawing.SystemColors.HighlightText,
                Padding = new Padding(0, 4, 0, 4) };
            this._gloabId = string.Format("{0}-{1}", System.Net.Dns.GetHostName(), DateTime.Now.ToString("yyyyMMddHHmmssfff"));
            this.txtExecSqlCommand.OwnerForm = this;         
        }

        /// <summary>
        /// 初始化 EditorText
        /// </summary>
        /// <param name="ContentText"></param>
        /// <param name="HighlightingName"></param>
        private void InitializeEditor(string ContentText, string HighlightingName = null)
        {
            string highlightingName = "C#";
            if (!string.IsNullOrEmpty(HighlightingName))
            {
                highlightingName = HighlightingName;
            }

            txtExecSqlCommand.Focus();
            UpdateTabControlProperties();
           
            txtExecSqlCommand.Text = ContentText;
            txtExecSqlCommand.SetHighlighting(highlightingName);

            txtExecSqlCommand.Document.FormattingStrategy = new DefaultFormattingStrategy();
            txtExecSqlCommand.Document.FoldingManager.FoldingStrategy = new TsqlFoldingStrategy();

            txtExecSqlCommand.TextChanged += new EventHandler(txtExecSqlCommand_TextChanged);           
            txtExecSqlCommand.ActiveTextAreaControl.TextArea.DragOver += new DragEventHandler(TextArea_DragOver);
            txtExecSqlCommand.ActiveTextAreaControl.TextArea.DragDrop += new DragEventHandler(TextArea_DragDrop);
            txtExecSqlCommand.ActiveTextAreaControl.TextArea.DragEnter += new DragEventHandler(TextArea_DragEnter);

            txtExecSqlCommand.Document.UndoStack.ActionRedone += new EventHandler(UndoStack_ActionRedone);
            txtExecSqlCommand.Document.UndoStack.ActionUndone += new EventHandler(UndoStack_ActionUndone);

        }

        /// <summary>
        /// 利用正则从SQL脚本中提取表名
        /// </summary>
        /// <param name="SqlText"></param>
        /// <returns></returns>
        private List<string> GetTablesNameFromSqlText(string SqlText)
        {
            List<string> rvl = new List<string>();

            string _sqltext = (string)SqlText.Clone();
            _sqltext = _sqltext.Replace('"', ' ');

            string[] pattern_array =new string[]{ 
                //@"\s+(from|join)\s+[\w\[\]]*\.?[\w\[\]]*\.?\[?(\b\w+)\]?[\r\n\s]*",
                "\\s+(from|join)\\s+[\\w\\[\\]]*\\.?[\\w\\[\\]]*\\.?\\[?(\\b\\w+)\\]?[\\r\\n\\s]*",
                "\\s+(from|join)\\s+\"\\w\\\"\\\"\"*\\.?\"\\w\\\"\\\"\"*\\.?\\\"?(\\b\\w+)\\\"?\"\\r\\n\\s\"*",                
            };
            foreach (string pattern in pattern_array)
            {
                System.Text.RegularExpressions.Regex regex =
               new System.Text.RegularExpressions.Regex(pattern, System.Text.RegularExpressions.RegexOptions.Compiled
                   | System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                System.Text.RegularExpressions.Match match = regex.Match(_sqltext);
                while (match.Success)
                {
                    string table_name = match.Groups[match.Groups.Count - 1].Value;
                    rvl.Add(table_name);
                    match = match.NextMatch();
                }
            }
            return rvl;
        }

        #endregion        
             
        #region 执行SQL命令

        private void RollbackCommandText(CommandRunner Runner)
        {
            if (AdoObject != null)
            {
                this.Invoke(new MethodInvoker(delegate()
                {
                    _MAINFORM.SetQueryFormToolBarItemEnabled(false);
                }));
                AdoObject.RollBack();
                rollbackTimes = rollbackTimes + 1;
                if (Runner != null)
                {
                    AdoObject.BeginTransaction();
                    this._tranBeginning = true;
                }
                else
                {
                    this._tranBeginning = false;
                }
                this._unCompleteCommand = false;
                    
                this.Invoke(new MethodInvoker(delegate()
                {
                    _MAINFORM.SetQueryFormToolBarItemEnabled(true);
                }));
            }
        }

        private void CommitCommandText(CommandRunner Runner)
        {
            if (AdoObject != null)
            {
                this.Invoke(new MethodInvoker(delegate()
                {
                    _MAINFORM.SetQueryFormToolBarItemEnabled(false);
                }));
                AdoObject.Commit();
                commitTimes = commitTimes + 1;
                if (Runner != null)
                {
                    AdoObject.BeginTransaction();
                    this._tranBeginning = true;
                }
                else
                {
                    this._tranBeginning = false;
                }
                this._unCompleteCommand = false;
                    
                this.Invoke(new MethodInvoker(delegate()
                {
                    _MAINFORM.SetQueryFormToolBarItemEnabled(true);
                }));
            }
        }

        private void ExecuteSingleCommandText(CommandText command, int ViewsCount, ListBox infolist)
        {
            if (_backgroudWorkerCancel)
                return;

            if (command.Text.ToUpper().StartsWith("USE"))
            {
                List<string> usebases = OSqlParse.UseParse(command.Text,DBServer.ProviderName);
                foreach (string usebase in usebases)
                {
                    infolist.Items.Add(MessageWriteLine("输出信息", "数据库 " + usebase + " 应用成功"));
                }
                _commandCode += "USE,";
            }
            else if (command.Text.ToUpper().StartsWith("EXEC")
            || command.Text.ToUpper().StartsWith("SELECT"))
            {
                if (command.Text.ToUpper().IndexOf("USE ") > 0)
                {
                    throw new Exception("USE附近语法有错误");
                }

                string tableName = String.Empty;
                if (command.Text.ToUpper().StartsWith("SELECT"))
                {
                    tableName = String.Join(",", GetTablesNameFromSqlText(command.Text).ToArray());
                }

                if (_backgroudWorkerCancel)
                    return;

                DataSet ds = AdoObject.GetDataSet(System.Data.CommandType.Text, command.Text, null);

                if (_backgroudWorkerCancel)
                {
                    ds.Dispose();
                    return;
                }

                if (ds.Tables.Count > 0)
                {
                    _commandCode += "SELECT,";
                }
                else
                {
                    _commandCode += "EXECUTE,";
                }
                
                foreach (DataTable table in ds.Tables)
                {
                    if (_backgroudWorkerCancel)
                    {
                        table.Dispose();
                        break;
                    }

                    if (table.TableName != "SchemaTable")
                    {
                        TabPage tabdatatable = new TabPage();
                        tabdatatable.BackColor = Color.White;
                        tabdatatable.Padding = new Padding(4);
                        tabdatatable.UseVisualStyleBackColor = false;
                        tabdatatable.Text = "视图"; //(ViewsCount > 0) ? "视图" + ViewsCount : "视图";
                        tabdatatable.ImageIndex = 2;
                        NDataGridView detail = new NDataGridView();
                        detail.BorderStyle = BorderStyle.None;
                        detail.ColumnHeadersDefaultCellStyle = _headCellStyle;
                        detail.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
                        detail.Dock = DockStyle.Fill;
                        detail.ShowRowNumber = _isShowRownumber;
                        detail.AllowUserToAddRows = false;                       
                        detail.ShowToastValue = new ShowToastValue(this.NDataGridView_ShowToastValue); 
                        tabdatatable.Controls.Add(detail);  
                        tabdatatable.Tag = tableName;
                        _tabPages.Add(tabdatatable);

                        if (_backgroudWorkerCancel)
                        {
                            table.Dispose();
                            break;
                        }

                        Application.DoEvents();
                        delayTimes += 150;//加载UI延迟150毫秒
                        totalselectRows += table.Rows.Count;
                        System.Threading.Thread.Sleep(150);
                        this.Invoke(new MethodInvoker(delegate() { detail.DataSource = table; }));
                        infolist.Items.Add(MessageWriteLine("输出信息", "共查询 " + table.Rows.Count + " 条数据"));
                        table.Dispose();
                        ViewsCount++;

                    }
                }
                ds.Dispose();
            }
            else
            {
                if (command.Text.ToUpper().IndexOf("USE ") > 0)
                {
                    throw new Exception("USE附近语法有错误");
                }

                if (_backgroudWorkerCancel)
                    return;

                int rows = AdoObject.Execute(System.Data.CommandType.Text, command.Text, null);
                if (rows != -1)
                {
                    infolist.Items.Add(MessageWriteLine("输出信息", "所影响行数 " + rows + " 行"));
                    totalexecuteRows += rows;
                }

                _commandCode += "EXECUTE,";

            }
        }

        private void ExecuteBatchCommandText(CommandRunner Runner)
        {
            if (DBServer != null && Runner != null)
            {               
                this.Invoke(new MethodInvoker(delegate()
                {
                    foreach (TabPage tp in ResultsTabControl.TabPages)
                    {
                        foreach (Control control in tp.Controls)
                        {
                            control.Dispose();
                        }
                        ResultsTabControl.TabPages.Remove(tp);
                        tp.Dispose();
                    }
                }));

                ListBox infolist = new ListBox();
                infolist.BorderStyle = BorderStyle.FixedSingle;               
                infolist.Margin = new Padding(0);
                infolist.ContextMenuStrip = this.contextMenuStrip1;    
                infolist.MouseClick+=infolist_MouseClick;

                try
                {
                    int ViewsCount = 0;

                    CommandBatch commandBatch = Runner.CommandBatch;

                    if (commandBatch == null)
                        throw new Exception("SQL执行语句为空");

                    foreach (CommandText command in commandBatch.CommandList)
                    {
                        if (_backgroudWorkerCancel)
                        {
                            break;
                        }

                        List<string> Prints = OSqlParse.PrintParse(command.Text, DBServer.ProviderName);                        
                        foreach (string print in Prints)
                        {
                            infolist.Items.Add(MessageWriteLine("输出信息", print));
                        }                       
                        ExecuteSingleCommandText(command, ViewsCount, infolist);                      
                    }
                   
                    GC.Collect();

                    Runner.EndTime = DateTime.Now;

                    _commandCode = _commandCode.TrimEnd(',');

                    TimeSpan ts = Runner.EndTime.Subtract(Runner.BeginTime);
                    double tricks = ts.TotalMilliseconds - delayTimes;
                    TimeSpan lts = TimeSpan.FromMilliseconds(tricks);
                    string msg = string.Format(
                        "共计用时：{0:00} 分 {1:00} 秒 {2:000} 毫秒",
                        lts.Minutes,
                        lts.Seconds,
                        lts.Milliseconds);

                    if (!_backgroudWorkerCancel)
                    {
                        infolist.Items.Add(MessageWriteLine("输出信息", "执行成功," + msg));

                        Runner.Result.Success = true;
                        Runner.Result.Message = "执行成功";

                        switch (_commandCode)
                        {
                            case "SELECT":
                                this.Invoke(new MethodInvoker(delegate()
                                {
                                    ExecuteReulstMessage.Text = "执行成功," + "共查询 " + (totalselectRows + 1) + " 条记录," + msg;
                                }));
                                break;
                            case "EXECUTE":
                                _unCompleteCommand = true;
                                this.Invoke(new MethodInvoker(delegate()
                                {
                                    ExecuteReulstMessage.Text = "执行成功," + "共影响 " + (totalexecuteRows + 1) + " 行," + msg;
                                }));
                                break;
                            default:
                                _unCompleteCommand = true;
                                this.Invoke(new MethodInvoker(delegate()
                                {
                                    ExecuteReulstMessage.Text = "执行成功," + msg;
                                }));
                                break;
                        }                        

                    }
                    else
                    {
                        infolist.Items.Add(MessageWriteLine("输出信息", "操作已取消," + msg));

                        Runner.Result.Success = true;
                        Runner.Result.Message = "执行完成";

                        this.Invoke(new MethodInvoker(delegate()
                        {
                            ExecuteReulstMessage.Text = "操作已取消," + msg;
                        }));
                    }                  

                }
                catch (Exception ex)
                {
                    string execeptionText = ex.Message;
                    execeptionText = execeptionText.Replace("\r\n", " ").Replace("\n", " ");
                    infolist.Items.Add(MessageWriteLine("错误信息", execeptionText));
                    Runner.Result.Success = false;
                    Runner.Result.Message = ex.Message;

                    try
                    {
                        this.Invoke(new MethodInvoker(delegate()
                        {
                            ExecuteReulstMessage.Text = "执行命令时出错,错误信息：" + execeptionText;
                        }));
                    }
                    catch
                    {

                    }
                    
                }                

                for (int i = 0, count = ResultsTabControl.TabCount; i < count; i++)
                    if (count > 1)
                        this.Invoke(new MethodInvoker(delegate() { ResultsTabControl.TabPages[i].Text = "视图 " + (i + 1); }));

                TabPage tabinfo = new TabPage();
                tabinfo.BackColor = Color.White;
                tabinfo.Padding = new Padding(4);
                tabinfo.UseVisualStyleBackColor = false;
                tabinfo.Text = "消息";
                tabinfo.ImageIndex = 0;               
                infolist.Dock = DockStyle.Fill;                 
                tabinfo.Controls.Add(infolist);
                _listBox = infolist;                 
                _tabPages.Add(tabinfo);

            }
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            CommandRunner runner = e.Argument as CommandRunner;
            if (!e.Cancel)
            {
                switch (runner.CommandType)
                {
                    case CommandTypes.Execute:
                        Delegate_ExecuteCommandText d1 = new Delegate_ExecuteCommandText(ExecuteBatchCommandText);
                        d1.Invoke(runner);
                        break;
                    case CommandTypes.Rollback:
                        Delegate_Rollback d2 = new Delegate_Rollback(RollbackCommandText);
                        d2.Invoke(runner);
                        break;
                    case CommandTypes.Commit:
                        Delegate_Commit d3 = new Delegate_Commit(CommitCommandText);
                        d3.Invoke(runner);
                        break;
                }             
                e.Result = runner;
            }
            else
            {
                runner.Result=new CommandResult() { Message = "命令被取消", Success = true };
                if (_unCompleteCommand)
                    runner.Result.CallBack = new CommandResultCallBack(DoUnCompleteTransation);
            }
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Result != null)
            {               
                foreach (TabPage page in _tabPages)
                {
                    ResultsTabControl.TabPages.Add(page);
                }
                //ResultsTabControl.ShowWaitMessage = false;
                //ProcessBox.Visible = false;
                ProcessBox.Close();

                CommandResult wr = ((CommandRunner)e.Result).Result;                             
                if (wr.CallBack != null)
                {
                    bool _commit = false;
                    if (MessageBox.Show(this, "有未提交的事作操作，是否要提交",
                        "信息提示", MessageBoxButtons.YesNo).Equals(DialogResult.Yes))
                        _commit = true;
                    wr.CallBack(null, _commit);
                }
                
                _MAINFORM.SetQueryFormToolBarItemEnabled(true);
            }
        }

        private void DoUnCompleteTransation(object sender, bool commit)
        {
            if (commit)
            {  
                this.CommitCommandText(null); 
            }
            else
            {
                this.RollbackCommandText(null);
            }
        }

        private void NDataGridView_ShowToastValue(object sender, ToastEventArgs e)
        {
            ShowCellValue show = new ShowCellValue(e.Value);
            show.ShowDialog(this);
        }

        #endregion

        #region QueryDocument 事件

        private void QueryDocument_Load(object sender, EventArgs e)
        {
            this.splitContainer1.SplitterDistance = this.splitContainer1.Height / 2;
        }

        private void UndoStack_ActionRedone(object sender, EventArgs e)
        {
            _MAINFORM.SetRedoMenuItem(true);
            _MAINFORM.SetUndoMenuItem(true);
            if (!txtExecSqlCommand.EnableRedo)
            {
                _MAINFORM.SetRedoMenuItem(false);
            }
            if (!txtExecSqlCommand.EnableUndo)
            {
                _MAINFORM.SetUndoMenuItem(false);
            } 
        }

        private void UndoStack_ActionUndone(object sender, EventArgs e)
        {
            _MAINFORM.SetRedoMenuItem(true);
            _MAINFORM.SetUndoMenuItem(true);
            if (!txtExecSqlCommand.EnableRedo)
            {
                _MAINFORM.SetRedoMenuItem(false);
            }
            if (!txtExecSqlCommand.EnableUndo)
            {
                _MAINFORM.SetUndoMenuItem(false);
            } 
        }

        private void txtExecSqlCommand_TextChanged(object sender, EventArgs e)
        {
            txtExecSqlCommand.Document.FoldingManager.UpdateFoldings();
        }

        private void infolist_MouseClick(object sender, MouseEventArgs e)
        {
            ListBox listBox = sender as ListBox;
            this.复制ToolStripMenuItem.Text = "复制文本";
            this.复制ToolStripMenuItem.Tag = "ListBox";
            this.粘贴ToolStripMenuItem.Enabled = false;            
        }
        
        private void 复制ToolStripMenuItem_Click(object sender, EventArgs e)
        {           
            string commandType = this.复制ToolStripMenuItem.Tag + "";
            switch (commandType)
            {
                case "ListBox":

                    if (_listBox != null)
                    {
                        _clipBoardValue = _listBox.SelectedItem == null ? "" : _listBox.SelectedItem.ToString();
                    }                   

                    break;
                case "TextEditorControl":

                    break;
            }

            if (string.IsNullOrEmpty(_clipBoardValue))
            {
                MessageBox.Show("复制内容为空");
                return;
            }

            try
            {
                Clipboard.Clear();
                Clipboard.SetData(DataFormats.Text, _clipBoardValue);
                //Clipboard.SetDataObject(_clipBoardValue,true);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }

        private void 粘贴ToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        #region 响应从左侧树拖动内容

        //托拽
        private void TextArea_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetData("System.Windows.Forms.TreeNode", false) != null)
            {
                TreeNode node = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode", false);
                if ((node.Tag.ToString() == "table") || (node.Tag.ToString() == "view"))
                    ((DragEventArgs)e).Effect = DragDropEffects.Copy;
                else
                    if (node.Tag.ToString() == "column")
                        ((DragEventArgs)e).Effect = DragDropEffects.Copy;

                return;
            }

            if (((DragEventArgs)e).Data.GetDataPresent(DataFormats.FileDrop))
                ((DragEventArgs)e).Effect = DragDropEffects.Copy;
            else
                ((DragEventArgs)e).Effect = DragDropEffects.None;

        }

        //托拽
        private void TextArea_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetData("System.Windows.Forms.TreeNode", false) != null)
            {
                TreeNode node = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode", false);
                //System.Drawing.Rectangle r = txtExecSqlCommand.RectangleToClient(txtExecSqlCommand.ClientRectangle);
                switch (node.Level)
                {
                    case 0:
                        string databaseName = string.Empty;
                        if (DBServer == (DataBaseServer)node.Tag)
                        {
                            databaseName = DBServer.DataBaseName;
                            switch (DBServer.ProviderName)
                            {
                                case "System.Data.SQL":
                                case "System.Data.Sql": databaseName = "[" + databaseName + "]"; break;
                                case "System.Data.Sqlite": databaseName = "[" + databaseName + "]"; break;
                                case "System.Data.OleDb": databaseName = "[" + databaseName + "]"; break;
                                case "System.Data.Postgresql":
                                case "System.Data.PostgreSql": databaseName = "\"" + databaseName + "\""; break;
                                case "System.Data.MySql": databaseName = "\"" + databaseName + "\""; break;
                                case "System.Data.Oracle": databaseName = "[" + databaseName + "]"; break;
                                default: break;
                            }
                            databaseName = "USE " + " " + databaseName + System.Environment.NewLine + "GO";                           
                        }
                        else
                        {
                            databaseName = ((DataBaseServer)node.Tag).DataBaseName;
                            switch (((DataBaseServer)node.Tag).ProviderName)
                            {
                                case "System.Data.SQL":
                                case "System.Data.Sql": databaseName = "[" + databaseName + "]"; break;
                                case "System.Data.Sqlite": databaseName = "[" + databaseName + "]"; break;
                                case "System.Data.OleDb": databaseName = "[" + databaseName + "]"; break;
                                case "System.Data.Postgresql":
                                case "System.Data.PostgreSql": databaseName = "\"" + databaseName + "\""; break;
                                case "System.Data.MySql": databaseName = "\"" + databaseName + "\""; break;
                                case "System.Data.Oracle": databaseName = "[" + databaseName + "]"; break;
                                default: break;
                            }                            
                        }
                        txtExecSqlCommand.ActiveTextAreaControl.TextArea.InsertString(databaseName);
                        break;
                    case 2:
                    case 3:
                    case 4:
                    case 5:                         
                        string objectName = node.Text;
                        if (node.Tag.ToString().Equals("column"))
                        {
                            if (!string.IsNullOrEmpty(objectName) && objectName.Contains("["))
                                objectName = node.Text.Substring(0, node.Text.LastIndexOf("["));

                            switch (DBServer.ProviderName)
                            {
                                case "System.Data.SQL":
                                case "System.Data.Sql": objectName = "[" + objectName + "]"; break;
                                case "System.Data.Sqlite": objectName = "[" + objectName + "]"; break;
                                case "System.Data.OleDb": objectName = "[" + objectName + "]"; break;
                                case "System.Data.Postgresql":
                                case "System.Data.PostgreSql": objectName = "\"" + objectName + "\""; break;
                                case "System.Data.MySql": objectName = "\"" + objectName + "\""; break;
                                case "System.Data.Oracle": objectName = "[" + objectName + "]"; break;
                                default: break;
                            }
                        }
                        else
                        {
                            switch (DBServer.ProviderName)
                            {
                                case "System.Data.SQL":
                                case "System.Data.Sql": objectName = "[" + objectName + "]"; break;
                                case "System.Data.Sqlite": objectName = "[" + objectName + "]"; break;
                                case "System.Data.OleDb": objectName = "[" + objectName + "]"; break;
                                case "System.Data.Postgresql":
                                case "System.Data.PostgreSql": objectName = "\"" + objectName + "\""; break;
                                case "System.Data.MySql": objectName = "\"" + objectName + "\""; break;
                                case "System.Data.Oracle": objectName = "[" + objectName + "]"; break;
                                default: break;
                            }
                        }
                        txtExecSqlCommand.ActiveTextAreaControl.TextArea.InsertString(objectName);
                        break;
                }


                //if (node.Tag != null && (node.Tag.ToString() == "table") || (node.Tag.ToString() == "view") || (node.Tag.ToString() == "column") ||
                //  (node.Tag.ToString() == "procedure") || (node.Tag.ToString() == "function"))
                //{
                //    System.Drawing.Rectangle r = txtExecSqlCommand.RectangleToClient(txtExecSqlCommand.ClientRectangle);
                //    TreeNode _dragObject = node;
                //    string objectName = _dragObject.Text;
                //    if (node.Tag.ToString().Equals("column"))
                //    {
                //        if (!string.IsNullOrEmpty(objectName) && objectName.Contains("["))
                //            objectName = node.Text.Substring(0, node.Text.LastIndexOf("["));

                //        switch (DBServer.ProviderName)
                //        {
                //            case "System.Data.SQL":
                //            case "System.Data.Sql": objectName = "[" + objectName + "]"; break;
                //            case "System.Data.Sqlite": objectName = "[" + objectName + "]"; break;
                //            case "System.Data.OleDb": objectName = "[" + objectName + "]"; break;
                //            case "System.Data.Postgresql":
                //            case "System.Data.PostgreSql": objectName = "\"" + objectName + "\""; break;
                //            case "System.Data.MySql": objectName = "\"" + objectName + "\""; break;
                //            case "System.Data.Oracle": objectName = "[" + objectName + "]"; break;
                //            default: break;
                //        }
                //    }
                //    else
                //    {
                //        switch (DBServer.ProviderName)
                //        {
                //            case "System.Data.SQL":
                //            case "System.Data.Sql": objectName = "[" + objectName + "]"; break;
                //            case "System.Data.Sqlite": objectName = "[" + objectName + "]"; break;
                //            case "System.Data.OleDb": objectName = "[" + objectName + "]"; break;
                //            case "System.Data.Postgresql":
                //            case "System.Data.PostgreSql": objectName = "\"" + objectName + "\""; break;
                //            case "System.Data.MySql": objectName = "\"" + objectName + "\""; break;
                //            case "System.Data.Oracle": objectName = "[" + objectName + "]"; break;
                //            default: break;
                //        }
                //    }                    

                //    //if ((node.Tag.ToString() == "procedure"))
                //    //{
                //    //    string ntext = node.Text;
                //    //    objectName = "EXEC " + objectName;
                //    //    DataTable _dt1 = AdoObject.GetTableObject(ntext);

                //    //    foreach (DataRow dr in _dt1.Rows)
                //    //    {
                //    //        objectName += Environment.NewLine;
                //    //        objectName += dr["ColumnName"] + "=" + "''" + Environment.NewLine;
                //    //    }

                //    //}
                //    //else if ((node.Tag.ToString() == "function"))
                //    //{
                //    //    string ntext = node.Text;
                //    //    objectName = "" + objectName + "()";
                //    //    DataTable _dt1 = AdoObject.GetTableObject(ntext);
                                               
                //    //    foreach (DataRow dr in _dt1.Rows)
                //    //    {
                //    //        objectName += Environment.NewLine;
                //    //        objectName += dr["ColumnName"] + "=" + "''" + Environment.NewLine;
                //    //    }
                //    //}

                //    txtExecSqlCommand.ActiveTextAreaControl.TextArea.InsertString(objectName);

                //}
                return;
            }

            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                // Assign the file names to a string array, in 
                // case the user has selected multiple files.
                string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
                try
                {
                    if (files.Length < 1)
                        return;
                    string fullName = files[0];
                    if (files.Length > 1)
                        return;
                    string fileName = Path.GetFileName(fullName);
                    if (!fileName.EndsWith(".sql", StringComparison.OrdinalIgnoreCase))
                        return;  
                 
                    string fileContent = "";
                    StreamReader sr = new StreamReader(fullName);
                    fileContent = sr.ReadToEnd();
                    sr.Close();
                    sr.Dispose();
                    sr = null;

                    txtExecSqlCommand.Text = fileContent;

                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    return;
                }
            }

        }

        //托拽
        private void TextArea_DragOver(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Copy;
        }

        #endregion

        private void toolButton_Click(object sender, EventArgs e)
        {
            var ButtonText = ((ToolStripButton)sender).Text;
            var SelectedTab = ResultsTabControl.SelectedTab;
            if (SelectedTab.Text != "消息")
            {
                string selectedtableName = SelectedTab.Tag + "";

                var control = SelectedTab.Controls[0];
                if (!control.GetType().Equals(typeof(NDataGridView)))
                    return;

                try
                {
                    Rectangle rect;
                    NDataGridView dgv = control as NDataGridView;
                    switch (ButtonText)
                    {
                        case "添加":
                            var dv = dgv.DataSource;
                            if (dv.GetType().Equals(typeof(DataTable)))
                            {
                                DataRow nrow = ((DataTable)dv).NewRow();
                                ((DataTable)dv).Rows.Add(nrow);
                            }
                            else if (dv.GetType().Equals(typeof(DataView)))
                            {
                                DataRow nrow = ((DataView)dv).Table.NewRow();
                                ((DataView)dv).Table.Rows.Add(nrow);
                            } 
                            break;
                        case "删除":
                            DataGridViewSelectedRowCollection rowCollection = dgv.SelectedRows;
                            List<DataGridViewRow> selectedrows = new List<DataGridViewRow>();
                            foreach (DataGridViewRow row in rowCollection)
                            {
                                selectedrows.Add(row);
                            }
                            foreach (DataGridViewRow row in selectedrows)
                            {
                                dgv.Rows.Remove(row);
                            }
                            break;
                        case "生成脚本":

                            ToolBarBox.Enabled = false;
                            ProgressBar progressBar = new ProgressBar() { Maximum = 100, Minimum = 0 };
                            rect = this.ResultsTabControl.ClientRectangle; //this.splitContainer1.Panel2.ClientRectangle;
                            rect.Y = this.Padding.Top + this.splitContainer1.Panel1.ClientRectangle.Height + this.ToolBarBox.Height + 1;
                            ProcessBox.ProgressBar = progressBar;
                            ProcessBox.Show(this.splitContainer1, rect);

                            System.Threading.Tasks.Task.Run(() =>
                            {
                                string SQLCode = DataObjectToSQL.ToInsertSQL(selectedtableName,
                                 dgv.DataSource, DBServer, progressBar);

                                if (!string.IsNullOrEmpty(SQLCode))
                                {
                                    this.Invoke(new MethodInvoker(delegate()
                                    {
                                        QueryDocument queryDocument = new QueryDocument(_MAINFORM);
                                        _MAINFORM.AddNewContent(queryDocument, selectedtableName + "-" + "SQL脚本");
                                        queryDocument.SetSqlCommandText(SQLCode);
                                        this.ExecuteReulstMessage.Text = "生成脚本成功";
                                    }));

                                }

                                this.Invoke(new MethodInvoker(delegate() { ToolBarBox.Enabled = true; this.ProcessBox.Close(); }));

                            });                             

                            break;

                        case "提交":

                            dgv.EndEdit();

                            rect = this.ResultsTabControl.ClientRectangle; //this.splitContainer1.Panel2.ClientRectangle;
                            rect.Y = this.Padding.Top + this.splitContainer1.Panel1.ClientRectangle.Height + this.ToolBarBox.Height + 1;
                            ProcessBox.WaitMessageBox = new Label();
                            ProcessBox.Show(this.splitContainer1, rect);

                            System.Threading.Tasks.Task.Run(() =>
                            {

                                DataTable dataTable = null;
                                var dataSource = dgv.DataSource;
                                if (dataSource.GetType().Equals(typeof(DataTable)))
                                {
                                    dataTable = dataSource as DataTable;
                                }
                                else if (dataSource.GetType().Equals(typeof(DataView)))
                                {
                                    dataTable = ((DataView)dataSource).Table;
                                }

                                if (dataTable == null)
                                    return;

                                DataTable dt = AdoObject.GetTableObject(selectedtableName);
                                DataRow[] rows = dt.Select(" CisNull like 'pk%' ");
                                if (rows == null || rows.Length < 1)
                                {
                                    this.Invoke(new MethodInvoker(delegate() { this.ExecuteReulstMessage.Text = "没有主键，数据更新失败"; }));
                                    return;
                                }

                                try
                                {
                                    //不能调用AcceptChanges 方法
                                    //dataTable.AcceptChanges();
                                    AdoObject.UpdateDataSet(dataTable.DataSet, DataObjectToSQL.ToTableDataEmptySQL(selectedtableName, dataTable, DBServer));

                                    switch (DBServer.ProviderName)
                                    {
                                        case "System.Data.SQL":
                                        case "System.Data.Sql":
                                        case "System.Data.PostgreSql":
                                        case "System.Data.Oracle":
                                        case "System.Data.MySql":
                                            if (AppSettings.EditorSettings.EnableDataBaseTran)
                                            {
                                                AdoObject.Commit();
                                                AdoObject.BeginTransaction();
                                            }
                                            break;
                                    }

                                    this.Invoke(new MethodInvoker(delegate()
                                    {
                                        this.ProcessBox.Close();
                                        this.ExecuteReulstMessage.Text = "数据已更新成功";
                                    }));
                                }
                                catch (Exception ex)
                                {
                                    this.Invoke(new MethodInvoker(delegate()
                                    {
                                        this.ProcessBox.Close();
                                        this.ExecuteReulstMessage.Text = ex.Message;
                                    }));
                                }                              

                            });
                            
                            break;

                        case "导出":
                                                       
                            SaveFileDialog savefileDialog = new SaveFileDialog();
                            savefileDialog.Title = "导出数据到Excel";
                            savefileDialog.Filter = "*.xls|*.xls";
                            savefileDialog.FileName = "" + selectedtableName + "";
                            if (savefileDialog.ShowDialog().Equals(DialogResult.OK))
                            {
                                ToolBarBox.Enabled = false;
                                rect = this.ResultsTabControl.ClientRectangle; //this.splitContainer1.Panel2.ClientRectangle;
                                rect.Y = this.Padding.Top + this.splitContainer1.Panel1.ClientRectangle.Height + this.ToolBarBox.Height + 1;
                                ProcessBox.WaitMessageBox = new Label();
                                ProcessBox.Show(this.splitContainer1, rect);

                                DataTable dataTable2 = null;
                                if (dgv.DataSource.GetType().Equals(typeof(DataTable)))
                                    dataTable2 = dgv.DataSource as DataTable;
                                else
                                    dataTable2 = (dgv.DataSource as DataView).Table;

                                if (dataTable2 == null)
                                    return;

                                if (!string.IsNullOrEmpty(savefileDialog.FileName))
                                    DevelopAssistant.Common.NpoiHelper.ExcelOutToFile(savefileDialog.FileName, dataTable2, "Sheet1", selectedtableName, null);

                                this.Invoke(new MethodInvoker(delegate() { ToolBarBox.Enabled = true; this.ProcessBox.Close(); }));
                                MessageBox.Show("导出成功");
                            }

                            break;

                        case "打印预览":

                            if (dgv != null)
                                dgv.PrintPreview();

                            break;

                        case "打印":

                            if (dgv != null)
                                dgv.Print();

                            break;

                        case "显示行号":

                            if (dgv.ShowRowNumber)
                            {
                                toolButtonShowNumber.Image = Properties.Resources._unchecked;
                                dgv.ShowRowNumber = false;
                                _isShowRownumber = false;
                                dgv.Invalidate();                                
                            }
                            else
                            {
                                toolButtonShowNumber.Image = Properties.Resources._checked;
                                dgv.ShowRowNumber = true;
                                _isShowRownumber = true;
                                dgv.Invalidate();                                
                            }                               

                            break;
                    }
                }
                catch (Exception ex)
                {
                    this.Invoke(new MethodInvoker(delegate() { this.ExecuteReulstMessage.Text = ex.Message; }));
                }               
            }
        }

        private void DisposeTask()
        {
            if (task != null && task.IsCompleted)
            {
                task.Dispose();
            }
        }

        private void 复制ToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            this.txtExecSqlCommand.ActiveTextAreaControl.TextArea.ClipboardHandler.Copy(null, null);
        }

        private void 粘贴ToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            this.txtExecSqlCommand.ActiveTextAreaControl.TextArea.ClipboardHandler.Paste(null, null);
        }

        private void 排版ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.TSQLToFormat();
        }

        private void 转成一行ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.TSQLToLine();
        }

        private void 清除ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.txtExecSqlCommand.Text = "";
            this.txtExecSqlCommand.Refresh();
        }

        private void 保存为ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveSqlFile();
        }

        private void 添加到收藏ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _MAINFORM.SnippetBar.AddSqlSnippetCode(DBServer.ConnectionString, DBServer.ProviderName, GetSelectionText());
        }

        private void toolButtonPrintPrewiew_Click(object sender, EventArgs e)
        {

        }

        private void toolButtonPrint_Click(object sender, EventArgs e)
        {

        }

        #endregion

        #region 公共属性

        public string ProviderName
        {
            get
            {
                return DBServer.ProviderName;
            }
        }

        public string ConnectionID {
            get
            {
                string relt = string.Empty;
                if (DBServer != null)
                {
                    relt = DBServer.ID;
                }
                return relt;
            }
        }

        public string ConnectionString
        {
            get
            {
                string relt = string.Empty;
                if (DBServer != null)
                {
                    relt = DBServer.ConnectionString;
                }
                return relt;
            }
        }
        
        public string AllText
        {
            set
            {
                txtExecSqlCommand.Text = value;
            }
            get
            {
                return txtExecSqlCommand.Text;
            }
        }

        public int TotalLines
        {
            get { return txtExecSqlCommand.Document.TotalNumberOfLines; }
        }

        public int CursorOffset
        {
            get { return txtExecSqlCommand.ActiveTextAreaControl.Caret.Offset; }
        }

        public string FileFilter
        {
            get { return "SQL Files (*.sql)|*.sql|All Files (*.*)|*.*"; }
        }

        public bool UnCompleteCommand
        {
            get {
                bool rvl = this._unCompleteCommand;               
                if (this.AdoObject != null 
                    && this.AdoObject.TransCompleteState())
                {
                    rvl = false;
                }                
                return rvl;
            }
        }

        public bool TranBeginning
        {
            get { return _tranBeginning; }
        }

        public string GloadID
        {
            get
            {
                return _gloabId;
            }
        }

        public ICSharpCode.TextEditor.TextEditorControl Editor
        {
            get { return this.txtExecSqlCommand; }
        }

        #endregion
        
        #region 公共方法

        public void SetServer(DataBaseServer server)
        {
            if (server != this.DBServer)
            {
                this.DBServer = server;
                this.AdoObject = Utility.GetAdohelper(DBServer);
                this.txtExecSqlCommand.DataBaseServer = DBServer;
            }           
        }

        public void ClearSelection()
        {
            txtExecSqlCommand.ActiveTextAreaControl.SelectionManager.ClearSelection();
        }

        public string GetSelectionText()
        {
            string selectedlLineText = txtExecSqlCommand.ActiveTextAreaControl.TextArea.SelectionManager.SelectedText;
            string sqlText = txtExecSqlCommand.Text;
            if (!string.IsNullOrEmpty(selectedlLineText))
            {
                sqlText = selectedlLineText;
            }
            return sqlText;
        }

        public void InsertText(string text)
        {
            if (string.IsNullOrEmpty(text))
            {
                return;
            }

            int offset = txtExecSqlCommand.ActiveTextAreaControl.Caret.Offset;

            // if some text is selected we want to replace it
            if (txtExecSqlCommand.ActiveTextAreaControl.SelectionManager.IsSelected(offset))
            {
                offset = txtExecSqlCommand.ActiveTextAreaControl.SelectionManager.SelectionCollection[0].Offset;
                txtExecSqlCommand.ActiveTextAreaControl.SelectionManager.RemoveSelectedText();
            }

            txtExecSqlCommand.Document.Insert(offset, text);
            int newOffset = offset + text.Length; // new offset at end of inserted text

            // now reposition the caret if required to be after the inserted text
            if (CursorOffset != newOffset)
            {
                SetCursorByOffset(newOffset);
            }

            txtExecSqlCommand.Focus();
        }

        public void SetEditorFont()
        {
            if (AppSettings.EditorSettings == null || AppSettings.EditorSettings.EditorFont == null)
                return;
            this.txtExecSqlCommand.Font = AppSettings.EditorSettings.EditorFont;
            this.txtExecSqlCommand.Refresh();
        }

        public int FindString(string value, int startIndex, StringComparison comparisonType)
        {
            if (startIndex < 0)
                return -1;

            ClearSelection();
            string text = AllText;
            if ((startIndex + value.Length) > AllText.Length)
            {
                return -1;
            }
            int pos = text.IndexOf(value, startIndex, comparisonType);
            if (pos > -1)
            {               
                HighlightString(pos, value.Length);
            }

            return pos;
        }

        public bool ReplaceString(string value, int startIndex, int length)
        {
            if (value == null || startIndex < 0 || length < 0)
            {
                return false;
            }

            if ((startIndex + length) > AllText.Length)
            {
                return false;
            }

            ClearSelection();

            txtExecSqlCommand.Document.Replace(startIndex, length, value);

            HighlightString(startIndex, value.Length);

            UndoStack_ActionUndone(this,new EventArgs());

            return true;
        }

        public bool ReplaceString(string value, int startIndex, int length, bool highlight)
        {
            if (value == null || startIndex < 0 || length < 0)
            {
                return false;
            }

            if ((startIndex + length) > AllText.Length)
            {
                return false;
            }

            ClearSelection();

            txtExecSqlCommand.Document.Replace(startIndex, length, value);

            if (highlight)
                HighlightString(startIndex, value.Length);

            UndoStack_ActionUndone(this, new EventArgs());

            return true;
        }

        public void HighlightString(int offset, int length)
        {
            if (offset < 0 || length < 1)
            {
                return;
            }

            int endPos = offset + length;
            txtExecSqlCommand.ActiveTextAreaControl.SelectionManager.SetSelection(
                txtExecSqlCommand.Document.OffsetToPosition(offset),
                txtExecSqlCommand.Document.OffsetToPosition(endPos));
            SetCursorByOffset(endPos);
        }

        public bool SetCursorByOffset(int offset)
        {
            if (offset >= 0)
            {
                txtExecSqlCommand.ActiveTextAreaControl.Caret.Position = txtExecSqlCommand.Document.OffsetToPosition(offset);
                return true;
            }

            return false;
        }

        public void FindAndReplace(FindAndReplaceRequest request)
        {
            if (string.IsNullOrEmpty(request.LookFor))
            {
                MessageBox.Show("没有要查找的字符!");
                return;
            }
            if (!string.IsNullOrEmpty(AllText))
            {
                if (AllText.IndexOf(request.LookFor, 0, request.StringComparison) < 0)
                {
                    ClearSelection();
                    MessageBox.Show(request.LookFor + "在文本中未找到");
                    return;
                }
                if (request.CommandText == "Look")
                {
                    int pos = FindString(request.LookFor, request.Position, request.StringComparison);
                    if (pos > -1)
                    {
                        request.Position = pos + request.LookFor.Length;
                    }
                    else
                    {
                        request.Position = 0;
                        FindAndReplace(request);
                    }
                }
                else if (request.CommandText == "Replace")
                {
                    int pos = FindString(request.LookFor, request.Position, request.StringComparison);
                    int len = request.LookFor.Length;                   
                    if (pos > -1)
                    {
                        ReplaceString(request.ReplaceWith, pos, len);
                        request.Position = pos + request.LookFor.Length;
                    }
                    else
                    {
                        request.Position = 0;
                        FindAndReplace(request);
                    }
                }
            }            
        }
        
        public void ExecuteSql(string SqlText)
        {          
            try
            {
                _tabPages = new List<TabPage>();

                var actcontent = _MAINFORM.GetSelectedContent();
                var contents = _MAINFORM.GetContents("QueryDocument");
                foreach (var content in contents)
                {
                    if (AppSettings.EditorSettings.EnableDataBaseTran &&
                        ((QueryDocument)content).UnCompleteCommand &&
                        !string.Equals(((QueryDocument)content).GloadID, ((QueryDocument)actcontent).GloadID))
                    {
                        bool _commit = false;
                        if (MessageBox.Show(this, "有未提交的事作操作，是否要提交",
                            "信息提示", MessageBoxButtons.YesNo).Equals(DialogResult.Yes))
                            _commit = true;
                        ((QueryDocument)content).DoUnCompleteTransation(null, _commit);
                    }
                }   
            }
            catch (Exception ex)
            {

            }

            delayTimes = 0;
            totalselectRows = -1;
            totalexecuteRows = -1;
            _commandCode = String.Empty;
            //ResultsTabControl.ShowWaitMessage = false;
            //ProcessBox.Visible = true;
            this.Invoke(new MethodInvoker(delegate()
            {
                this.splitContainer1.Panel2Collapsed = false;
                _MAINFORM.SetQueryFormToolBarItemEnabled(false);
            }));

            Rectangle rect = this.ResultsTabControl.ClientRectangle; //this.splitContainer1.Panel2.ClientRectangle;
            rect.Y = this.Padding.Top + this.splitContainer1.Panel1.ClientRectangle.Height + this.ToolBarBox.Height + 1;
            ProcessBox.WaitMessageBox = new Label();
            ProcessBox.Show(this.splitContainer1, rect);

            _backgroudWorkerCancel = false;
            CommandRunner runner = new CommandRunner();
            runner.BeginTime = DateTime.Now;
            runner.SqlText = SqlText;
            backgroundWorker1.RunWorkerAsync(runner);
        }

        public void SetSqlCommandText(string SqlText)
        {
            this.txtExecSqlCommand.Text = SqlText;
            this.txtExecSqlCommand.Refresh();
            //this.txtExecSqlCommand.Invalidate();
        }

        public void SaveFile()
        {
            SaveFileDialog dlg_SaveToFile = new SaveFileDialog();
            dlg_SaveToFile.Filter = "*.sql";
            if (dlg_SaveToFile.ShowDialog(this).Equals(DialogResult.OK))
            {
                string FileName = dlg_SaveToFile.FileName;
                if (FileName == null)
                {
                    throw new InvalidOperationException("The 'FileName' cannot be null");
                }
                txtExecSqlCommand.SaveFile(FileName);
            }
        }

        public void TSQLToFormat()
        {
            string oldTextCode = this.txtExecSqlCommand.Text;
            string FormatSQLText = DevelopAssistant.Format.TsqlFormatHelper.FormatToTSQL(oldTextCode);             
            //this.txtExecSqlCommand.Text = FormatSQLText;
            //this.txtExecSqlCommand.Document.Replace(0, this.txtExecSqlCommand.Document.TextContent.Length, FormatSQLText);
            ReplaceString(FormatSQLText, 0, oldTextCode.Length);
            this.txtExecSqlCommand.Refresh();
        }

        public void TSQLToExecute()
        {
            ExecuteSql(GetSelectionText());
        }

        public void TSQLCommit()
        {
            _tabPages = new List<TabPage>();
            switch (DBServer.ProviderName)
            {
                case "System.Data.SQL":
                case "System.Data.Sql":
                case "System.Data.PostgreSql":
                case "System.Data.Oracle":
                case "System.Data.MySql":
                    _backgroudWorkerCancel = false;
                    if (!backgroundWorker1.IsBusy)
                        backgroundWorker1.RunWorkerAsync(new CommandRunner() { CommandType = CommandTypes.Commit });
                break;
                default:
                MessageBox.Show("" + _dbTypeName + "不支持事务提交");
                break;
            }            
        }

        public void TSQLRollback()
        {
            _tabPages = new List<TabPage>();
            switch (DBServer.ProviderName)
            {
                case "System.Data.SQL":
                case "System.Data.Sql":
                case "System.Data.PostgreSql":
                case "System.Data.Oracle":
                case "System.Data.MySql":
                     _backgroudWorkerCancel = false;
                     if (!backgroundWorker1.IsBusy)
                         backgroundWorker1.RunWorkerAsync(new CommandRunner() { CommandType = CommandTypes.Rollback });
                    break;
                default :
                    MessageBox.Show("" + _dbTypeName + "不支持事务提交");
                    break;
            }           
        }

        public void TSQLStop()
        {
            if (!_backgroudWorkerCancel)
            {
                _backgroudWorkerCancel = true;
                this.backgroundWorker1.CancelAsync();
                //DoUnCompleteTransation(null,false);
            }             
        }

        public void TSQLToLine()
        {
            string textcode = GetSelectionText();
            if (string.IsNullOrEmpty(textcode))
            {
                textcode = this.txtExecSqlCommand.Text;
            }
            string oldTextCode = textcode;
            textcode = textcode.Replace("values(", "values (");
            textcode = textcode.Replace(");", ") ;");
            textcode = System.Text.RegularExpressions.Regex.Replace(textcode, "[\n\r]+", " ");
            textcode = System.Text.RegularExpressions.Regex.Replace(textcode, "[\\s]+", "<k>");
            textcode = textcode.Replace("<k>", " ");             
            //this.txtExecSqlCommand.Text = textcode;
            //this.txtExecSqlCommand.Document.Replace(0, this.txtExecSqlCommand.Document.TextContent.Length, textcode);
            ReplaceString(textcode, 0, oldTextCode.Length);
            this.txtExecSqlCommand.Refresh();
        }

        public void Redo()
        {
            txtExecSqlCommand.Redo(); 
        }

        public void Undo()
        {
            txtExecSqlCommand.Undo();
        }

        public void OpenSqlFile()
        {
            OpenFileDialog dlg_openfile = new OpenFileDialog();
            dlg_openfile.Filter = "SQL脚本文件|*.sql";
            if (dlg_openfile.ShowDialog().Equals(DialogResult.OK))
            {
                if (dlg_openfile.FileName != "")
                {
                    using (System.IO.StreamReader strReader = new StreamReader(dlg_openfile.FileName, Encoding.UTF8))
                    {
                        string oldTextCode = txtExecSqlCommand.Text;
                        string strSqlText = strReader.ReadToEnd();
                        //txtExecSqlCommand.Text = strSqlText;
                        ReplaceString(strSqlText, 0, oldTextCode.Length, false);
                        txtExecSqlCommand.Refresh();
                    }
                }
            }
        }

        public void SaveSqlFile()
        {
            SaveFileDialog dlg_savefile = new SaveFileDialog();
            dlg_savefile.Filter = "SQL脚本文件|*.sql";
            if (dlg_savefile.ShowDialog().Equals(DialogResult.OK))
            {
                if (dlg_savefile.FileName != "")
                {
                    using (System.IO.StreamWriter strwrite = new StreamWriter(dlg_savefile.FileName, false, Encoding.UTF8))
                    {
                        strwrite.Write(txtExecSqlCommand.Text);
                    }
                }
            }
        }

        #endregion

    }
}
